home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / lisp / wgdb-42.lha / wgdb-4.2 / gdb / nindy-share / demux.h < prev    next >
C/C++ Source or Header  |  1992-09-11  |  3KB  |  98 lines

  1. /******************************************************************************
  2.  * This include file supports demultiplexing of input from two sources:
  3.  * stdin and one external source (normally the NINDY monitor).
  4.  *
  5.  * Its purpose is to promote portability of applications between different
  6.  * flavors (BSD and USG/SysV) of Unix.  As of this writing, it is used by the
  7.  * gdb960 remote communications module (remote.c) and the comm960 utility.
  8.  * 
  9.  * It is assumed that 'USG' is defined on the compiler invocation line if the
  10.  * code should compile and run on a USG/SysV system.  Otherwise, BSD is assumed.
  11.  *
  12.  * The application code must use all three of these macros:
  13.  *
  14.  *    DEMUX_DECL    Declares data structures needed by the other macros.
  15.  *
  16.  *    DEMUX_WAIT(fd)    Waits until input is available on either stdin or
  17.  *            file descriptor 'fd'.
  18.  *
  19.  *    DEMUX_READ(fd,bufp,bufsz)
  20.  *            Reads up to 'bufsz' bytes from file descriptor 'fd'
  21.  *            into buffer pointed at by character pointer 'bufp'.
  22.  *            Returns the number of bytes read, which will be 0
  23.  *            if there was no input pending on 'fd'. 'fd' should be
  24.  *            either 0 (stdin) or the same descriptor that was used
  25.  *            in the invocation of 'DEMUX_WAIT'.
  26.  *
  27.  * The following macro is also included:
  28.  *
  29.  *    TIME_INPUT(fd,timeout,retp)
  30.  *            Waits up to 'timeout' seconds for input on file
  31.  *            descriptor 'fd'.  Sets (*retp) to:
  32.  *                 1 if input is ready
  33.  *                 0 if timeout occurred
  34.  *                -1 if wait was interrupted by a signal
  35.  *
  36.  * WARNINGS ABOUT USG (System V) UNIX!!
  37.  *
  38.  *    The TIME_INPUT macro isn't implemented: it's a no-op.
  39.  *
  40.  *    The damned 'poll' call can't be used on normal tty's, so DEMUX_WAIT is
  41.  *    also a no-op: DEMUX_READ uses the FIONREAD ioctl if it's available;
  42.  *    otherwise the file descriptor is temporarily set for non-blocking input
  43.  *    and a read it done.
  44.  *
  45.  ******************************************************************************/
  46.  
  47. #ifdef USG
  48. #    include <fcntl.h>
  49.  
  50. #    define DEMUX_DECL        int _saveflags_; int _n_
  51. #    define DEMUX_WAIT(fd)
  52.  
  53.     /* Use non-blocking I/O */
  54. #    define DEMUX_READ(fd,bufp,bufsz) (            \
  55.             _saveflags_ = fcntl( fd, F_GETFL, 0 ),        \
  56.             fcntl( fd, F_SETFL, _saveflags_ | O_NDELAY ),    \
  57.             _n_ = read( fd, bufp, bufsz ),            \
  58.             fcntl( fd, F_SETFL, _saveflags_ ),        \
  59.             _n_ )
  60.  
  61. #    define TIME_INPUT(fd,timeout,retp)
  62.  
  63. #else    /* BSD */
  64.  
  65. #    include <sys/types.h>
  66. #    include <sys/time.h>
  67.  
  68. #    define DEMUX_DECL    fd_set _mux_
  69.  
  70. #    define DEMUX_WAIT(fd)    {                    \
  71.             FD_ZERO( &_mux_ );                \
  72.             FD_SET( 0, &_mux_ );                \
  73.             FD_SET( fd, &_mux_ );                \
  74.             if (select(fd+1,&_mux_,0,0,0) <= 0){        \
  75.                 FD_ZERO(&_mux_);            \
  76.             }                        \
  77.     }
  78.             /* Check return value of select in case of
  79.              * premature termination due to signal:  clear
  80.              * file descriptors in this case so DEMUX_READ
  81.              * doesn't mistakenly say there's input on them.
  82.              */
  83.  
  84. #    define DEMUX_READ(fd,bufp,bufsz) \
  85.             ( FD_ISSET(fd,&_mux_) ?    read(fd,bufp,bufsz) : 0 )
  86.  
  87. #    define TIME_INPUT(fd,timeout,retp)    {            \
  88.             fd_set _fds_;                    \
  89.             struct timeval _timeout_;            \
  90.             FD_ZERO( &_fds_ );                \
  91.             FD_SET( fd, &_fds_ );                \
  92.             _timeout_.tv_sec  = timeout;            \
  93.             _timeout_.tv_usec = 0;                \
  94.             *(retp) = select(fd+1,&_fds_,0,0,&_timeout_);    \
  95.     }
  96.  
  97. #endif
  98.